// 添加必要的导入
import { EcommerceAutomationApp } from '../app.js';
import { cronConfig } from '../config/index.js';
import { logInfo, logError } from '../logger.js';
// 添加cron模块导入
import cron from 'node-cron';

class CronService {
  constructor() {
    this.tasks = new Map();
    this.jobs = {}; // 存储任务对象
    this.taskStatus = {}; // 存储任务状态
    this.maxRetries = 3; // 最大重试次数
  }

  /**
   * 启动所有定时任务
   */
  startAll() {
    logInfo('启动所有定时任务');

    // 处理退款任务（按平台）
    Object.keys(cronConfig).forEach(taskKey => {
      if (taskKey.endsWith('Refund')) {
        const taskConfig = cronConfig[taskKey];
        if (taskConfig.enabled) {
          const platform = taskKey.replace('Refund', '').toLowerCase();
          const accounts = taskConfig.accounts;
          const cronExpr = taskConfig.cron;
          const jobId = `refunds_${platform}`;

          this.jobs[jobId] = cron.schedule(cronExpr, async () => {
            this._updateTaskStatus(jobId, 'running');
            logInfo(`[定时任务] 开始执行${platform}退款处理，账户: ${accounts.join(', ')}`);
            await this.executeTaskWithRetry(platform, 'refunds', accounts, jobId);
          });

          logInfo(`已启动${platform}退款处理定时任务，表达式: ${cronExpr}`);
        }
      }
    });

    // 物流报告任务
    if (cronConfig.shipmentReport && cronConfig.shipmentReport.enabled) {
      const taskConfig = cronConfig.shipmentReport;
      const cronExpr = taskConfig.cron;
      const accounts = taskConfig.accounts;
      const jobId = 'shipment_report';

      this.jobs[jobId] = cron.schedule(cronExpr, async () => {
        this._updateTaskStatus(jobId, 'running');
        logInfo('[定时任务] 开始执行物流报告任务');
        await this.executeTaskWithRetry('shipment', null, accounts, jobId);
      });

      logInfo(`已启动物流报告定时任务，表达式: ${cronExpr}`);
    }

    // 退款统计任务
    if (cronConfig.refundStatistics && cronConfig.refundStatistics.enabled) {
      const taskConfig = cronConfig.refundStatistics;
      const cronExpr = taskConfig.cron;
      const accounts = taskConfig.accounts;
      const jobId = 'refund_statistics';

      this.jobs[jobId] = cron.schedule(cronExpr, async () => {
        this._updateTaskStatus(jobId, 'running');
        logInfo('[定时任务] 开始执行退款统计任务');
        await this.executeTaskWithRetry('statistics', null, accounts, jobId);
      });

      logInfo(`已启动退款统计定时任务，表达式: ${cronExpr}`);
    }

    // 换货待处理订单数任务
    if (cronConfig.exchangePendingCount && cronConfig.exchangePendingCount.enabled) {
      const taskConfig = cronConfig.exchangePendingCount;
      const cronExpr = taskConfig.cron;
      const accounts = taskConfig.accounts;
      const jobId = 'exchange_pending';

      this.jobs[jobId] = cron.schedule(cronExpr, async () => {
        this._updateTaskStatus(jobId, 'running');
        logInfo('[定时任务] 开始执行换货待处理订单数任务');
        await this.executeTaskWithRetry('exchange', 'all', accounts, jobId);
      });

      logInfo(`已启动换货待处理订单数定时任务，表达式: ${cronExpr}`);
    }
  }

  /**
   * 带重试机制的任务执行
   */
  async executeTaskWithRetry(platform, action, accountKeys, jobId) {
    let retries = 0;
    while (retries <= this.maxRetries) {
      try {
        await this.executeTask(platform, action, accountKeys);
        this._updateTaskStatus(jobId, 'completed');
        logInfo(`[定时任务] ${jobId} 执行成功`);
        return;
      } catch (error) {
        retries++;
        if (retries > this.maxRetries) {
          this._updateTaskStatus(jobId, 'failed', error.message);
          logError(`[定时任务] ${jobId} 执行失败，已达到最大重试次数(${this.maxRetries})`);
          return;
        }
        this._updateTaskStatus(jobId, 'retrying', `第${retries}次重试`);
        logInfo(`[定时任务] ${jobId} 执行失败，${retries}秒后进行第${retries}次重试...`);
        await new Promise(resolve => setTimeout(resolve, retries * 1000));
      }
    }
  }

  /**
   * 更新任务状态
   */
  _updateTaskStatus(jobId, status, message = '') {
    this.taskStatus[jobId] = {
      status,
      message,
      timestamp: new Date().toISOString()
    };
    logInfo(`[任务状态] ${jobId}: ${status} ${message}`);
  }

  /**
   * 获取所有任务状态
   */
  getStatus() {
    return Object.keys(this.taskStatus).reduce((acc, jobId) => {
      acc[jobId] = this.taskStatus[jobId];
      return acc;
    }, {});
  }

  /**
   * 停止所有任务
   */
  stopAll() {
    logInfo('停止所有定时任务');
    Object.values(this.jobs).forEach(job => job.stop());
    this.jobs = {};
    // 更新所有任务状态为已停止
    Object.keys(this.taskStatus).forEach(jobId => {
      if (this.taskStatus[jobId].status === 'running') {
        this._updateTaskStatus(jobId, 'stopped', '任务已被手动停止');
      }
    });
  }

  /**
   * 执行特定任务
   * @param {string} platform - 平台名称
   * @param {string} action - 操作名称
   */
  async executeTask(platform, action = null, accountKeys = null) {
    // 添加任务超时控制
    const TIMEOUT = 30 * 60 * 1000; // 30分钟超时
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error(`任务执行超时 (${TIMEOUT}ms)`)), TIMEOUT);
    });

    try {
      // 使用Promise.race添加超时控制
      await Promise.race([
        this._executeTaskWithTimeout(platform, action, accountKeys),
        timeoutPromise
      ]);
    } catch (error) {
      logError(`执行${platform}${action ? ':' + action : ''}任务时出错: ${error.stack || error}`);
      // 可以在这里添加通知机制，告知任务失败
    }
  }

  /**
   * 带超时的任务执行（内部方法）
   */
  async _executeTaskWithTimeout(platform, action = null, accountKeys = null) {
    // statistics 统计任务不需要浏览器
    if (platform === 'statistics') {
      logInfo(`执行定时任务: ${platform}${action ? ':' + action : ''}`);
      // 计算时间范围
      const { startTime, endTime } = this.calculateTimeRange(
        cronConfig.refundStatistics.timeRange.start,
        cronConfig.refundStatistics.timeRange.end
      );
      // 直接调用统计，无需浏览器
      await (new EcommerceAutomationApp()).runRefundStatistics(startTime, endTime);
      return;
    }

    const app = new EcommerceAutomationApp();
    try {
      await app.init(platform);
      logInfo(`执行定时任务: ${platform}${action ? ':' + action : ''}`);

      if (platform === 'shipment') {
        await app.runShipmentReport(accountKeys || shipmentAccounts);
      } else if (platform === 'exchange' && action === 'all') {
        await app.runExchangePendingCountAll(accountKeys || exchangeAccounts);
      } else if (platform === 'statistics') {
        const { startTime, endTime } = this.calculateTimeRange(
          cronConfig.refundStatistics.timeRange.start,
          cronConfig.refundStatistics.timeRange.end
        );
        await app.runRefundStatisticsBatch(accountKeys || statisticsAccounts, startTime, endTime);
      } else if (action === 'refunds') {
        await app.runRefundProcessBatch(accountKeys);
      } else {
        // 其它平台任务
        await app.createContext(platform);
        // 可扩展更多平台和操作
      }
    } catch (error) {
      logError(`执行${platform}${action ? ':' + action : ''}任务时出错: ${error.stack || error}`);
      throw error; // 重新抛出错误，让上层处理
    } finally {
      await app.close().catch(err => {
        logError(`关闭资源时出错: ${err.message}`);
      });
    }
  }

  /**
   * 计算时间范围
   * @param {string} start - 开始时间配置
   * @param {string} end - 结束时间配置
   * @returns {Object} 包含格式化开始和结束时间的对象
   */
  calculateTimeRange(start, end) {
    const now = new Date();
    let startTime, endTime;

    // 如果配置的是昨天的完整日期范围
    if (start === '-1d' && end === 'now') {
      // 设置为昨天的00:00:00到今天的00:00:00
      const today = new Date(now);
      today.setHours(0, 0, 0, 0);

      endTime = new Date(today);
      startTime = new Date(today);
      startTime.setDate(startTime.getDate() - 1);
    } else {
      // 原有的时间计算逻辑
      // 解析开始时间
      if (start === 'now') {
        startTime = now;
      } else if (start.startsWith('-')) {
        // 相对时间，例如 -24h, -7d
        const match = start.match(/-(\d+)([a-zA-Z])/);
        if (match) {
          const value = parseInt(match[1]);
          const unit = match[2];

          startTime = new Date(now);
          switch (unit) {
            case 'h': // 小时
              startTime.setHours(startTime.getHours() - value);
              break;
            case 'd': // 天
              startTime.setDate(startTime.getDate() - value);
              break;
            case 'm': // 分钟
              startTime.setMinutes(startTime.getMinutes() - value);
              break;
            default:
              startTime = new Date(now.getTime() - 24 * 60 * 60 * 1000); // 默认24小时前
          }
        } else {
          // 默认24小时前
          startTime = new Date(now.getTime() - 24 * 60 * 60 * 1000);
        }
      } else {
        // 绝对时间，尝试解析
        startTime = new Date(start) || new Date(now.getTime() - 24 * 60 * 60 * 1000);
      }

      // 解析结束时间
      if (end === 'now') {
        endTime = now;
      } else {
        // 尝试解析为绝对时间
        endTime = new Date(end) || now;
      }
    }

    // 格式化为指定的字符串格式
    const formatTime = (date) => {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      const seconds = String(date.getSeconds()).padStart(2, '0');
      return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
    };

    return {
      startTime: formatTime(startTime),
      endTime: formatTime(endTime)
    };
  }

  /**
   * 获取任务状态
   * @returns {Object} 任务状态信息
   */
  getStatus() {
    const status = {};
    for (const [name, task] of this.tasks) {
      status[name] = {
        enabled: cronConfig[name]?.enabled || false,
        cron: cronConfig[name]?.cron || '',
        running: !!task // 只要注册了就算“运行中”
      };
    }
    return status;
  }
}

// 添加导出语句
export { CronService };

export default new CronService();